#include <string.h>
#include <memory.h>
#include <limits.h>
#include <ctype.h>
#include <getopt.h>

#include "test_lib.h"
#include "func.h"

char* record_process_rss(const char* suffix)
{
	char time_str[64];
	static char buffer[1024];
	time_t now = time(NULL);
	struct tm *tm_now = localtime(&now);

	float vmsize, vmrss;

	do {
		now = time(NULL);
		if (now == ((time_t)-1)) {
			fprintf(stderr, "time returned 0\n");
			break;
		}
		tm_now = localtime(&now);
		if (tm_now == NULL) {
			fprintf(stderr, "localtime returned 0\n");
			break;
		}
		if (strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_now) == 0) {
			fprintf(stderr, "strftime returned 0\n");
			break;
		}

		get_process_rss(&vmsize, &vmrss);

		if (suffix)
			snprintf(buffer, 1023, "[%s]: VmSize:%.6f  VmRSS:%.6f\t%s\n", time_str, vmsize, vmrss, suffix);
		else
			snprintf(buffer, 1023, "[%s]: VmSize:%.6f  VmRSS:%.6f\n", time_str, vmsize, vmrss);
	} while (0);
	return buffer;
}

int32_t print_json(cJSON* root)
{
	char buffer[65536] = {0};
	int32_t size;
	if(cJSON_PrintPreallocated(root, buffer, 65535, 1)) {
		size = printf("%s\n", buffer);
		printf("buffer_len=%d\n", strlen(buffer));
		memset(buffer, 0, 65536);
	} else {
		char* json_str = cJSON_Print(root);
		size = printf("%s\n", json_str);
		printf("json_len=%d\n", strlen(json_str));
		free(json_str);
	}
	return size;
}

int arg_opt(struct CtrlParam* param, int argc, char *argv[])
{
	int opt;
	int verbose_flag = 0;

	// 定义长选项
	static struct option long_options[] = {
		{"help",        no_argument,       0, 'h'},
		{"type",        required_argument, 0, 't'},
		{"module",      required_argument, 0, 'm'},
		{"count",       required_argument, 0, 'c'},
		{"record-int",  required_argument, 0, 'r'},
		{"log",         required_argument, 0, 'l'},
		{0, 0, 0, 0}
	};

	while ((opt = getopt_long(argc, argv, "h:t:m:c:r:l:", 
					long_options, NULL)) != -1) {
		switch (opt) {
			case 'h':
				printf("用法: %s [选项]\n", argv[0]);
				printf("选项:\n");
				printf("  -h, --help         显示帮助信息\n");
				printf("  -t, --type         指定模式, list: 监控设备列表; node:监控单个设备\n");
				printf("  -m, --module       指定监控设备名(仅在node模式有效),如:cpu, disk, cpie, temp, net, memory\n");
				printf("  -c, --count        指定监控次数\n");
				printf("  -r, --record-int   每r次监控记录一次日志\n");
				printf("  --log              指定日志文件\n");
				exit(EXIT_SUCCESS);

			case 't':
				if (strncmp(optarg, "list", 4) == 0) {
					param->type = 1;
				} else if (strncmp(optarg, "node", 4) == 0) {
					param->type = 2;
				} else {
					param->err += 1;;
				}
				break;

			case 'm':
				{
					char* p;
					if (strncmp(optarg, "cpu", 3) == 0) {
						param->module = 1;
						p = optarg+3;
					} else if (strncmp(optarg, "disk", 4) == 0) {
						param->module = 2;
						p = optarg+4;
					} else if (strncmp(optarg, "cpie", 4) == 0) {
						param->module = 6;
						p = optarg+4;
					} else if (strncmp(optarg, "temp", 4) == 0) {
						param->module = 5;
						p = optarg+4;
					} else if (strncmp(optarg, "net", 3) == 0) {
						param->module = 4;
						p = optarg+3;
					} else if (strncmp(optarg, "memory", 6) == 0) {
						param->module = 3;
						p = optarg+6;
					} else {
						param->err += 1;;
					}
					if (*p != 0 && !isspace(*p)) {
						printf("Unknown module:%s\n", optarg);
						param->err += 1;;
					}
				}
				break;

			case 'c':
				param->count = atoi(optarg);
				if (param->count == INT_MAX || param->count <= 0) {
					param->err += 1;
				}
				break;
			case 'r':
				param->record_interval = atoi(optarg);
				if (param->record_interval == INT_MAX || param->record_interval < 1) {
					param->err += 1;
				}
				break;
			case 'l':
				{
					if (strlen(optarg)>511) {
						printf("log filename too lang\n");
						param->err += 1;
						break;
					}
					snprintf(param->log, 511, "%s", optarg);
					FILE* log = fopen(param->log, "w");
					if (log == NULL) {
						printf("open log file failed\n");
						param->err += 1;
						break;
					}
					fclose(log);
				}
				break;
			default:
				fprintf(stderr, "Unrecognized options:%c\n", opt);
				exit(EXIT_FAILURE);
		}
	}

	// 处理非选项参数
	if (optind < argc) {
		printf("非选项参数:\n");
		while (optind < argc) {
			printf("  %s\n", argv[optind++]);
		}
	}

	return 0;
}


